package com.hengpeng.common.scheduling.quartz;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Scheduler;

import com.hengpeng.common.configuration.ConfigProvider;
import com.hengpeng.common.configuration.ConfigProviderFactory;
import com.hengpeng.common.scheduling.ScheduleConfig;
import com.hengpeng.common.scheduling.ScheduleExcute;
import com.hengpeng.common.util.ObjectHelper;

/**
 * <pre>
 * 定时作业框架
 * </pre>
 * @author chenhui
 * @version 1.0, 2013-1-5
 */
public class QuartzScheduleExcute
{
	private static final Log logger = LogFactory.getLog(QuartzScheduleExcute.class);

	private final static String SCHEDULE_CONFIG_FILEPATH = "schedule-config.xml";

	private final static Map<String, QuartzSchedule> taskMap = new ConcurrentHashMap<String, QuartzSchedule>();

	private final static Map<String, ScheduleConfig> configMap = new ConcurrentHashMap<String, ScheduleConfig>();

	private final static Map<String, List<String>> triggerMap = new ConcurrentHashMap<String, List<String>>();

	public static void startAllTask(Scheduler scheduler)
	{
		try
		{
			if (taskMap.size() > 0)
			{
				logger.error("当前有任务调度在执行，请先停止所有任务调度再启动所有任务调度.");
			}
			else
			{
				ConfigProvider<ScheduleConfig> cp = ConfigProviderFactory.getInstance(SCHEDULE_CONFIG_FILEPATH,
						ScheduleConfig.class);
				Map<String, ScheduleConfig> map = cp.getAllConfig();
				configMap.clear();
				for (Map.Entry<String, ScheduleConfig> entry : map.entrySet())
				{
					ScheduleConfig lconfig = entry.getValue();
					configMap.put(lconfig.getKey(), lconfig);
					if (taskMap.containsKey(lconfig.getKey()))
					{
						logger.error("任务调度[" + lconfig.getName() + "]已经有另一个实例启动.");
					}
					else
					{
						try
						{
							QuartzSchedule logictask = new QuartzSchedule(lconfig, scheduler);
							logictask.start(triggerMap);// 开始任务侦听
							taskMap.put(lconfig.getKey(), logictask);
							logger.info("任务调度[" + lconfig.getName() + "]开始启动, "
									+ ScheduleExcute.getIteratorDescription(lconfig));
						}
						catch (Exception e)
						{
							logger.error("开始任务调度[" + lconfig.getName() + "]时异常", e);
						}
					}
				}
				scheduler.addSchedulerListener(new QuartzSchedulerListener());
				logger.info("所有任务调度启动完毕,调度任务触发器{" + ObjectHelper.toPropertiesString(triggerMap) + "}");
			}
		}
		catch (Exception e)
		{
			logger.error("定时作业启动遇到错误", e);
		}
	}

	/**
	 * <pre>
	 * 停止所有任务
	 * </pre>
	 * @param scheduler
	 */
	public static void stopAllTask(Scheduler scheduler)
	{
		try
		{
			for (Map.Entry<String, List<String>> entry : triggerMap.entrySet())
			{
				for (String trigger : entry.getValue())
				{
					try
					{
						scheduler.unscheduleJob(trigger, Scheduler.DEFAULT_GROUP);
					}
					catch (Exception e)
					{
						logger.error("停止所有任务调度时报错{" + entry.getKey() + "," + trigger + "}", e);
					}
				}
			}
			taskMap.clear();
			triggerMap.clear();
			logger.info("所有任务调度停止完毕,调度任务触发器{" + ObjectHelper.toPropertiesString(triggerMap) + "}");
		}
		catch (Exception e)
		{
			logger.error("停止所有调度任务失败", e);
		}
	}

	/**
	 * <pre>
	 * 启动指定的定时作业
	 * </pre>
	 * @param scheduler
	 * @param scheduleName
	 */
	public static void startTaskByName(Scheduler scheduler, String scheduleName)
	{
		if (taskMap.containsKey(scheduleName))
		{
			taskMap.get(scheduleName).start(triggerMap);
		}
		else
		{
			if (configMap.containsKey(scheduleName))
			{
				ScheduleConfig lconfig = configMap.get(scheduleName);
				QuartzSchedule logictask = new QuartzSchedule(lconfig, scheduler);
				logictask.start(triggerMap);// 开始任务侦听
				taskMap.put(lconfig.getKey(), logictask);
				logger.info("任务调度[" + lconfig.getName() + "]开始启动, " + ScheduleExcute.getIteratorDescription(lconfig));
			}
			else
			{
				logger.error("开启调度任务失败{" + scheduleName + "}内存中不存在任务作业和调度配置信息");
			}
		}
	}

	/**
	 * <pre>
	 * 停止指定的任务
	 * </pre>
	 * @param scheduler
	 * @param scheduleName
	 */
	public static void stopTaskByName(Scheduler scheduler, String scheduleName)
	{
		if (triggerMap.containsKey(scheduleName))
		{
			List<String> triggers = triggerMap.get(scheduleName);
			for (String trigger : triggers)
			{
				try
				{
					scheduler.unscheduleJob(trigger, Scheduler.DEFAULT_GROUP);
				}
				catch (Exception e)
				{
					logger.error("停止指定任务调度时报错{" + scheduleName + "," + trigger + "}", e);
				}
			}
			taskMap.remove(scheduleName);
			triggerMap.remove(scheduleName);
		}
	}
}
